package studyguide.ch11;

import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.TiledLayer;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

public class BGGameMidlet extends MIDlet {

	private static final int NUM_COLUMS = 7;
	private static final int NUM_ROWS = 7;
	
	private final Command exitCommand;
	private final Display display;
	private GameTask gameTask;
	
	private final MyGameCanvas gameCanvas;
	private final Graphics graphics;
	
	private final TiledLayer background;
	private final TiledLayer maze;
	
	// Translated origin
	private final int tx;
	private final int ty;
	private int movingBrickIndex;
	
	private class SampleCommandListener implements CommandListener {
		public void commandAction(Command command, Displayable displayable) {
			if (command == exitCommand) {
				destroyApp(true);
				notifyDestroyed();
			} else {
				throw new RuntimeException("UNKNOWN COMMAND" + command);
			}
		}
	}
	
	private class GameTask extends TimerTask {
		public void run() {
			gameLoop();
		}
	}
	
	public BGGameMidlet() throws IOException {
		gameCanvas = new MyGameCanvas();
		graphics = gameCanvas.getGraphics();
		Image bgImage = Image.createImage("/game/background.png");
		Image mazeImage = Image.createImage("/game/brick.png");
		
		background = new TiledLayer(NUM_COLUMS, NUM_ROWS, bgImage, bgImage.getWidth(), bgImage.getHeight());
		// mazeImage.getWidth() / 3 because we have 3 tiles on the image
		maze = new TiledLayer(NUM_COLUMS, NUM_ROWS, mazeImage, mazeImage.getWidth() / 3, mazeImage.getHeight());
		
		background.fillCells(0, 0, NUM_COLUMS, NUM_ROWS, 1);
		maze.fillCells(0, 0, NUM_COLUMS, 1, 1);
		maze.fillCells(0, 0, 1, NUM_ROWS, 1);
		
		// Create a movable brick on the middle of the maze:
		movingBrickIndex = maze.createAnimatedTile(2);
		maze.setCell(NUM_COLUMS/2, NUM_ROWS/2, movingBrickIndex);
		
		
		maze.fillCells(NUM_COLUMS-1, 0, 1, NUM_ROWS, 1);
		maze.fillCells(0, NUM_ROWS-1, NUM_COLUMS, 1, 1);
		
		exitCommand = new Command("Exit", Command.EXIT, 1);
		
		gameCanvas.addCommand(exitCommand);
		
		SampleCommandListener listener = new SampleCommandListener();
		gameCanvas.setCommandListener(listener);
		display = Display.getDisplay(this);
		
		// Centers maze on screen changing screen origin:
		tx = gameCanvas.getWidth()/2 - background.getWidth()/2;
		ty = gameCanvas.getHeight()/2 - background.getHeight()/2;
		
		// Change origin:
		graphics.translate(tx, ty);
	}
	
	protected void destroyApp(boolean unconditional) {
		gameTask.cancel();
	}

	protected void pauseApp() {
		gameTask.cancel();
	}

	protected void startApp() throws MIDletStateChangeException {
		display.setCurrent(gameCanvas);
		// Start the game loop
		Timer timer = new Timer();
		gameTask = new GameTask();
		timer.schedule(gameTask, 0, 1000/5); // 5 frames per second
	}

	protected void gameLoop() {
		// Clear screen 
		graphics.setGrayScale(225); // gray
		graphics.fillRect(0, 0, gameCanvas.getWidth(), gameCanvas.getHeight());
		
		// Update the animated tile
		int animatedTile = maze.getAnimatedTile(movingBrickIndex);
		if (animatedTile == 2) {
			maze.setAnimatedTile(movingBrickIndex, 3);
		} else {
			maze.setAnimatedTile(movingBrickIndex, 2);
		}
		
		// Paint all objects:
		background.paint(graphics);
		maze.paint(graphics);
		
		// Flush to output
		gameCanvas.flushGraphics();
	}
	
}
